//
//  LocationManager.swift
//  Library_y
//
//  Created by JC on 2023/6/6.
//

import Foundation
import MapKit

/// 定位成功/失败协议
public protocol JCLocationManagerDelegate {
    func locationManager(didFailWithError error: Swift.Error)
    func locationManager(didUpdateLocation location: JCLocation)
}

/// 地址坐标类
public class JCLocation {
    
    public var coordinate: CLLocationCoordinate2D?      // 经纬度坐标
    public var address = ""                             // 格式化地址
}

// MARK: - 外部接口
extension JCLocationManager {
    
    /// 更新定位位置
    public func startUpdatingLocation() {
        locateManager.delegate = self
        locateManager.startUpdatingLocation()
        isLocationSuccess = false
    }
}

/// 获取当前位置
final public class JCLocationManager: NSObject {
    
    /// 是否定位成功
    fileprivate var isLocationSuccess: Bool = false
    
    /// 创建一个单例
    static public let share = JCLocationManager()
    
    /// 定位协议
    public var jcDelegate: JCLocationManagerDelegate?
    
    /// 位置类
    fileprivate var location = JCLocation()
    
    /// 位置管理对象
    private lazy var locateManager : CLLocationManager = {
        let locate  = CLLocationManager()
        locate.delegate = self
        locate.requestWhenInUseAuthorization()
        return locate
    }()
    
}

/// 获取用户当前位置
extension JCLocationManager: CLLocationManagerDelegate {
    
    // 获取位置请求
    public func requestAuthorization() {
        locateManager.requestWhenInUseAuthorization()
    }
    
    // 定位成功触发
    public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard !isLocationSuccess else { return }
        Log_y.print_("位置信息已经更新")
        locateManager.stopUpdatingLocation()
        guard let lat = locations.first?.coordinate.latitude, let lon = locations.first?.coordinate.longitude else {
            return }
        location.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon)
        reverseGeocode(latitude: lat, longitude: lon)
        isLocationSuccess = true
    }
    
    // 定位失败出发
    public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        Log_y.print_("定位失败：\(error.localizedDescription)")
        locateManager.stopUpdatingLocation()
        jcDelegate?.locationManager(didFailWithError: error)
    }
}

extension JCLocationManager {
    
    // 地理信息反编码
    internal func reverseGeocode(latitude: Double, longitude: Double) {
        let geocoder = CLGeocoder()
        let currentLocation = CLLocation(latitude: latitude, longitude: longitude)
        geocoder.reverseGeocodeLocation(currentLocation, completionHandler: {
            [weak self](placemarks:[CLPlacemark]?, error:Error?) -> Void in
            
            guard let placemarksArr = placemarks, !placemarksArr.isEmpty, let placemark = placemarksArr.first else { return }
            guard let adressDict = placemark.addressDictionary else { return }
            var address = ""
            if let state = adressDict["State"] as? String {
                address.append(state)
            }
            if let city = adressDict["City"] as? String {
                address.append(city)
            }
            if let subLocality = adressDict["SubLocality"] as? String {
                address.append(subLocality)
            }
            if let street = adressDict["Street"] as? String {
                address.append(street)
            }
            self?.location.address = address
            guard let locate = self?.location else { return }
            self?.jcDelegate?.locationManager(didUpdateLocation: locate)
        })
    }
}
